package com.geek.factory.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.geek.factory.constant.SuccessConstant;
import com.geek.factory.entity.StockCheck;
import com.geek.factory.entity.Warehouse;
import com.geek.factory.result.Result;
import com.geek.factory.service.IStockCheckService;
import com.geek.factory.service.IWarehouseService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 库存盘点管理控制器
 */
@RestController
@RequestMapping("/stock-check")
@Api(tags = "后台系统的 - 库存盘点模块")
@Slf4j
@CrossOrigin
public class StockCheckController {

    @Autowired
    private IStockCheckService stockCheckService;

    @Autowired
    private IWarehouseService warehouseService;

    @ApiOperation("生成盘点单号")
    @GetMapping("/generate-number")
    public Result generateCheckNumber() {
        try {
            // 生成盘点单号：PD + 年月日 + 时分秒
            String prefix = "PD";  // PD = Physical Check
            String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
            String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmmss"));
            String checkNo = prefix + dateStr + timeStr;

            Map<String, String> result = new HashMap<>();
            result.put("checkNo", checkNo);

            return new Result(SuccessConstant.SUCCESS, "生成成功", result);
        } catch (Exception e) {
            log.error("生成盘点单号失败", e);
            return new Result(SuccessConstant.FAIL, "生成盘点单号失败");
        }
    }

    @ApiOperation("新增库存盘点")
    @PostMapping("/add")
    public Result addStockCheck(@RequestBody StockCheck stockCheck) {
        try {
            // 设置默认值
            stockCheck.setStatus("draft");
            stockCheck.setCheckedItems(0);
            stockCheck.setDifferenceItems(0);
            stockCheck.setCreatedTime(LocalDateTime.now());
            stockCheck.setUpdatedTime(LocalDateTime.now());

            // 设置创建人（这里可以根据实际登录用户设置）
            stockCheck.setCreatedBy("admin");

            // 如果没有设置盘点日期，默认为今天
            if (stockCheck.getCheckDate() == null) {
                stockCheck.setCheckDate(LocalDate.now());
            }

            // 如果没有设置盘点单号，自动生成
            if (StringUtils.isBlank(stockCheck.getCheckNo())) {
                String prefix = "PD";  // PD = Physical Check
                String dateStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
                String timeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmmss"));
                String checkNo = prefix + dateStr + timeStr;
                stockCheck.setCheckNo(checkNo);
            }

            // 验证必填字段
            if (StringUtils.isBlank(stockCheck.getCheckName())) {
                return new Result(SuccessConstant.FAIL, "盘点名称不能为空");
            }
            if (stockCheck.getWarehouseId() == null) {
                return new Result(SuccessConstant.FAIL, "仓库不能为空");
            }
            if (StringUtils.isBlank(stockCheck.getCheckType())) {
                return new Result(SuccessConstant.FAIL, "盘点类型不能为空");
            }
            if (StringUtils.isBlank(stockCheck.getResponsiblePerson())) {
                return new Result(SuccessConstant.FAIL, "负责人不能为空");
            }

            boolean isSuccess = stockCheckService.save(stockCheck);
            log.info("新增库存盘点: {}, 结果: {}", stockCheck, isSuccess);
            if (isSuccess) {
                // 关联仓库信息
                if (stockCheck.getWarehouseId() != null) {
                    Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                    if (warehouse != null) {
                        stockCheck.setWarehouseName(warehouse.getWarehouseName());
                    }
                }
                return new Result(SuccessConstant.SUCCESS, "新增成功", stockCheck);
            }
            return new Result(SuccessConstant.FAIL, "新增失败");
        } catch (Exception e) {
            log.error("新增库存盘点失败", e);
            return new Result(SuccessConstant.FAIL, "新增失败：" + e.getMessage());
        }
    }

    @ApiOperation("通过ID查询库存盘点信息")
    @GetMapping("/{checkId}")
    public Result findStockCheckById(@ApiParam("盘点ID") @PathVariable("checkId") Integer checkId) {
        // 检查参数是否为空或无效
        if (checkId == null) {
            return new Result(SuccessConstant.FAIL, "盘点ID不能为空");
        }
        
        StockCheck stockCheck = stockCheckService.getById(checkId);
        log.info("stockCheck: {}", stockCheck);
        if (stockCheck != null) {
            // 关联仓库信息
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
            return new Result(SuccessConstant.SUCCESS, "ok", stockCheck);
        }
        return new Result(SuccessConstant.FAIL, "库存盘点记录不存在");
    }

    @ApiOperation("新增库存盘点（兼容旧接口）")
    @PostMapping
    public Result addStockCheckOld(@RequestBody StockCheck stockCheck) {
        return addStockCheck(stockCheck);
    }

    @ApiOperation("根据ID删除库存盘点")
    @DeleteMapping("/{checkId}")
    public Result deleteStockCheck(@ApiParam("盘点ID") @PathVariable("checkId") Integer checkId) {
        // 检查盘点状态，只有草稿状态才能删除
        StockCheck stockCheck = stockCheckService.getById(checkId);
        if (stockCheck == null) {
            return new Result(SuccessConstant.FAIL, "盘点记录不存在");
        }
        if (!"draft".equals(stockCheck.getStatus())) {
            return new Result(SuccessConstant.FAIL, "只能删除草稿状态的记录");
        }

        boolean isSuccess = stockCheckService.removeById(checkId);
        log.info("删除库存盘点ID: {}, 结果: {}", checkId, isSuccess);
        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "删除成功");
        }
        return new Result(SuccessConstant.FAIL, "删除失败");
    }

    @ApiOperation("批量删除库存盘点")
    @DeleteMapping("/batch")
    public Result batchDeleteStockCheck(@RequestBody Map<String, List<Integer>> request) {
        List<Integer> checkIds = request.get("checkIds");
        if (checkIds == null || checkIds.isEmpty()) {
            return new Result(SuccessConstant.FAIL, "请选择要删除的盘点记录");
        }

        // 检查所有记录是否都是草稿状态
        List<StockCheck> stockChecks = stockCheckService.listByIds(checkIds);
        for (StockCheck check : stockChecks) {
            if (!"draft".equals(check.getStatus())) {
                return new Result(SuccessConstant.FAIL, "只能删除草稿状态的记录");
            }
        }

        boolean isSuccess = stockCheckService.removeByIds(checkIds);
        log.info("批量删除库存盘点IDs: {}, 结果: {}", checkIds, isSuccess);
        if (isSuccess) {
            return new Result(SuccessConstant.SUCCESS, "批量删除成功");
        }
        return new Result(SuccessConstant.FAIL, "批量删除失败");
    }

    @ApiOperation("修改库存盘点信息")
    @PutMapping("/{checkId}")
    public Result updateStockCheck(@ApiParam("盘点ID") @PathVariable("checkId") Integer checkId, @RequestBody StockCheck stockCheck) {
        stockCheck.setCheckId(checkId);
        stockCheck.setUpdatedTime(LocalDateTime.now());

        boolean isSuccess = stockCheckService.updateById(stockCheck);
        log.info("修改库存盘点: {}, 结果: {}", stockCheck, isSuccess);
        if (isSuccess) {
            // 关联仓库信息
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
            return new Result(SuccessConstant.SUCCESS, "修改成功", stockCheck);
        }
        return new Result(SuccessConstant.FAIL, "修改失败");
    }

    @ApiOperation("更新盘点状态")
    @PutMapping("/{checkId}/status")
    public Result updateCheckStatus(
            @ApiParam("盘点ID") @PathVariable("checkId") Integer checkId,
            @RequestBody Map<String, String> request
    ) {
        String status = request.get("status");
        if (StringUtils.isBlank(status)) {
            return new Result(SuccessConstant.FAIL, "状态不能为空");
        }

        StockCheck stockCheck = stockCheckService.getById(checkId);
        if (stockCheck == null) {
            return new Result(SuccessConstant.FAIL, "盘点记录不存在");
        }

        stockCheck.setStatus(status);
        stockCheck.setUpdatedTime(LocalDateTime.now());

        // 根据状态设置开始时间和结束时间
        if ("in_progress".equals(status) && stockCheck.getStartTime() == null) {
            stockCheck.setStartTime(LocalDateTime.now());
        } else if ("completed".equals(status)) {
            stockCheck.setEndTime(LocalDateTime.now());
        }

        boolean isSuccess = stockCheckService.updateById(stockCheck);
        log.info("更新盘点状态: checkId={}, status={}, 结果: {}", checkId, status, isSuccess);
        if (isSuccess) {
            // 关联仓库信息
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
            return new Result(SuccessConstant.SUCCESS, "状态更新成功", stockCheck);
        }
        return new Result(SuccessConstant.FAIL, "状态更新失败");
    }

    @ApiOperation("更新盘点进度")
    @PutMapping("/{checkId}/progress")
    public Result updateCheckProgress(
            @ApiParam("盘点ID") @PathVariable("checkId") Integer checkId,
            @RequestBody Map<String, Object> request
    ) {
        Integer checkedItems = (Integer) request.get("checkedItems");
        Integer differenceItems = (Integer) request.get("differenceItems");

        if (checkedItems == null) {
            return new Result(SuccessConstant.FAIL, "已盘点数量不能为空");
        }

        StockCheck stockCheck = stockCheckService.getById(checkId);
        if (stockCheck == null) {
            return new Result(SuccessConstant.FAIL, "盘点记录不存在");
        }

        stockCheck.setCheckedItems(checkedItems);
        if (differenceItems != null) {
            stockCheck.setDifferenceItems(differenceItems);
        }
        stockCheck.setUpdatedTime(LocalDateTime.now());

        // 根据进度自动更新状态
        if (stockCheck.getTotalItems() != null && checkedItems >= stockCheck.getTotalItems()) {
            stockCheck.setStatus("completed");
            stockCheck.setEndTime(LocalDateTime.now());
        } else if (checkedItems > 0 && !"in_progress".equals(stockCheck.getStatus())) {
            stockCheck.setStatus("in_progress");
            if (stockCheck.getStartTime() == null) {
                stockCheck.setStartTime(LocalDateTime.now());
            }
        }

        boolean isSuccess = stockCheckService.updateById(stockCheck);
        log.info("更新盘点进度: checkId={}, checkedItems={}, differenceItems={}, 结果: {}",
                checkId, checkedItems, differenceItems, isSuccess);
        if (isSuccess) {
            // 关联仓库信息
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
            return new Result(SuccessConstant.SUCCESS, "进度更新成功", stockCheck);
        }
        return new Result(SuccessConstant.FAIL, "进度更新失败");
    }

    @ApiOperation("分页查询库存盘点列表")
    @GetMapping("/page")
    public Result getStockCheckPage(
            @RequestParam(defaultValue = "1") Integer pageNum,
            @RequestParam(defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String checkNo,
            @RequestParam(required = false) String checkName,
            @RequestParam(required = false) Integer warehouseId,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String checkType,
            @RequestParam(required = false) String responsiblePerson,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate
    ) {
        QueryWrapper<StockCheck> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(checkNo)) {
            wrapper.like("check_no", checkNo);
        }
        if (StringUtils.isNotBlank(checkName)) {
            wrapper.like("check_name", checkName);
        }
        if (warehouseId != null) {
            wrapper.eq("warehouse_id", warehouseId);
        }
        if (StringUtils.isNotBlank(status)) {
            wrapper.eq("status", status);
        }
        if (StringUtils.isNotBlank(checkType)) {
            wrapper.eq("check_type", checkType);
        }
        if (StringUtils.isNotBlank(responsiblePerson)) {
            wrapper.like("responsible_person", responsiblePerson);
        }
        if (StringUtils.isNotBlank(startDate)) {
            wrapper.ge("check_date", startDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            wrapper.le("check_date", endDate);
        }
        wrapper.orderByDesc("created_time");

        Page<StockCheck> page = stockCheckService.page(new Page<>(pageNum, pageSize), wrapper);

        // 关联仓库信息
        for (StockCheck stockCheck : page.getRecords()) {
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
        }

        Map<String, Object> data = new HashMap<>();
        data.put("records", page.getRecords());
        data.put("total", page.getTotal());
        data.put("current", page.getCurrent());
        data.put("size", page.getSize());
        data.put("pages", page.getPages());

        return new Result(SuccessConstant.SUCCESS, "查询成功", data);
    }

    @ApiOperation("获取所有库存盘点列表")
    @GetMapping("/list")
    public Result getAllStockChecks() {
        List<StockCheck> stockChecks = stockCheckService.list();
        // 关联仓库信息
        for (StockCheck stockCheck : stockChecks) {
            if (stockCheck.getWarehouseId() != null) {
                Warehouse warehouse = warehouseService.getById(stockCheck.getWarehouseId());
                if (warehouse != null) {
                    stockCheck.setWarehouseName(warehouse.getWarehouseName());
                }
            }
        }
        return new Result(SuccessConstant.SUCCESS, "查询成功", stockChecks);
    }


    @ApiOperation("获取盘点统计信息")
    @GetMapping("/stats")
    public Result getStockCheckStats() {
        Map<String, Object> stats = new HashMap<>();

        // 统计各状态的盘点数量
        QueryWrapper<StockCheck> totalWrapper = new QueryWrapper<>();
        long totalChecks = stockCheckService.count(totalWrapper);

        QueryWrapper<StockCheck> draftWrapper = new QueryWrapper<>();
        draftWrapper.eq("status", "draft");
        long draftChecks = stockCheckService.count(draftWrapper);

        QueryWrapper<StockCheck> inProgressWrapper = new QueryWrapper<>();
        inProgressWrapper.eq("status", "in_progress");
        long inProgressChecks = stockCheckService.count(inProgressWrapper);

        QueryWrapper<StockCheck> completedWrapper = new QueryWrapper<>();
        completedWrapper.eq("status", "completed");
        long completedChecks = stockCheckService.count(completedWrapper);

        stats.put("totalChecks", totalChecks);
        stats.put("draftChecks", draftChecks);
        stats.put("inProgressChecks", inProgressChecks);
        stats.put("completedChecks", completedChecks);
        stats.put("completionRate", totalChecks > 0 ? (double) completedChecks / totalChecks * 100 : 0);

        return new Result(SuccessConstant.SUCCESS, "查询成功", stats);
    }


    @ApiOperation("获取单个盘点单统计信息")
    @GetMapping("/stats/{checkId}")
    public Result getStockCheckDetailStats(@ApiParam("盘点ID") @PathVariable("checkId") Integer checkId) {
        Map<String, Object> stats = new HashMap<>();

        StockCheck stockCheck = stockCheckService.getById(checkId);
        if (stockCheck == null) {
            return new Result(SuccessConstant.FAIL, "盘点记录不存在");
        }

        stats.put("checkId", stockCheck.getCheckId());
        stats.put("checkNo", stockCheck.getCheckNo());
        stats.put("checkName", stockCheck.getCheckName());
        stats.put("status", stockCheck.getStatus());
        stats.put("totalItems", stockCheck.getTotalItems());
        stats.put("checkedItems", stockCheck.getCheckedItems());
        stats.put("differenceItems", stockCheck.getDifferenceItems());
        stats.put("checkProgress", stockCheck.getTotalItems() != null && stockCheck.getTotalItems() > 0
                ? (double) stockCheck.getCheckedItems() / stockCheck.getTotalItems() * 100 : 0);
        stats.put("differenceRate", stockCheck.getCheckedItems() != null && stockCheck.getCheckedItems() > 0
                ? (double) stockCheck.getDifferenceItems() / stockCheck.getCheckedItems() * 100 : 0);

        return new Result(SuccessConstant.SUCCESS, "查询成功", stats);
    }


    @ApiOperation("获取待盘点任务列表（用于大屏展示）")
    @GetMapping("/pending-checks")
    public Result getPendingChecks(
            @ApiParam("限制数量") @RequestParam(defaultValue = "12") Integer limit) {
        try {
            List<StockCheck> checks = stockCheckService.getPendingChecks(limit);
            return new Result(SuccessConstant.SUCCESS, "查询成功", checks);
        } catch (Exception e) {
            log.error("获取待盘点任务失败", e);
            return new Result(SuccessConstant.FAIL, "查询失败");
        }
    }
}